home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
net3d-0.08
/
client.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-22
|
12KB
|
453 lines
/* client.c
*
* code to connect to the server and call other functions to run
* the game
*/
#include "net3d.h"
static void displayhelp(char *);
bool singlep=false; /* is this a net-game? */
char *pnames[MAX_PLAYERS]; /* names of all players */
int sock; /* connection to server */
int main(int argc, char **argv)
{
char name[100]=""; /* this player's name */
struct object *ohead=NULL; /* in-game object list */
struct vehicle *vhead=NULL; /* in-game vehicle list */
struct map mp; /* game world terrain details */
int number; /* client's player number */
struct vehicle *drive; /* vehicle client is driving */
bool alive; /* is this player still alive */
double ltime; /* time at last check of fps */
#if DISPLAYFPS
int frm=0; /* frames drawn */
#endif
struct view vw; /* player's 3d viewpoint */
int vmode=4; /* view of player's vehicle */
struct vehicle *pvehicles[MAX_PLAYERS]; /* vehicles players drive */
int plcount; /* number of people playing */
double servertime=0.0; /* game time from server */
bool winner=false; /* has someone won? */
FILE *dotfp; /* fp for .surrealrc file */
char dotsurpath[80]; /* file path to .surrealrc */
int drvid; /* vid of current vehicle */
struct point zpoint={0,0,0}; /* constant 0,0,0 point */
int finalcountdown = 100; /* after death, the number of frames
* until exit */
char currentdir[100]; /* path to .v file in current dir */
char net3ddir[100]; /* path to .v file in NET3D_DIR */
int i; /* scratch */
struct vehicle *vpos;
FILE *tfp;
/* initialize the default map.
*/
mp.ht = mp.gr = NULL; /* No hills by default */
mp.map_w = mp.map_h = 0;
mp.size = mp.scale = 0.0;
mp.lookout.x = 0; mp.lookout.y = 0; mp.lookout.z = 0;
mp.rfade = 0; mp.gfade = 0; mp.bfade = 0; /* fade to black */
mp.tcol = mp.gcol = 2; /* green hills & ground */
mp.skycol = 32; /* black sky */
mp.ground = True; /* ground does exist */
mp.stars = NULL; mp.scount = 0; /* no stars */
/* Display user help.
*/
if (argc == 1) {
printf("usage : Single player : %s <vehicle files>\n",argv[0]);
printf(" Network game : %s <server> <player name>\n",argv[0]);
printf(" Help : %s -help\n",argv[0]);
exit(0);
}
if (!strcmp(argv[1],"-help")) {
displayhelp(argv[0]);
exit(0);
}
/* setup sin and cos caches */
initcaches();
/* We want children automatically reaped by default */
signal(SIGCHLD,SIG_IGN);
/* read key configuration file.
*/
sprintf(dotsurpath,"%s/%s",getenv("HOME"),KEYFILE);
if ((dotfp = fopen(dotsurpath,"r"))) {
readkeyfile(dotfp);
fclose(dotfp);
}
readextravehicles();
/* Look for a file named by the first command line argument, in the current
* directory and NET3D_DIR. If it exists, then this is a single player game.
* If not, then the first command line argument is the name of the server,
* and this is a multi-player game.
*/
sprintf(currentdir,"%s",argv[1]);
sprintf(net3ddir,"%s/%s",NET3D_DIR,argv[1]);
if ((tfp = fopen(currentdir,"r")) || (tfp = fopen(net3ddir,"r"))) {
/* using single player mode.
*/
fclose(tfp);
singlep=true;
/* read map and vehicle files.
*/
for(i=1; i<argc; i++) {
int pifd;
struct stat dummy;
/* look for the vehicle file in the current directory, or
* if not found, in the directory defined by NET3D_DIR.
*/
sprintf(currentdir,"%s",argv[i]);
sprintf(net3ddir,"%s/%s",NET3D_DIR,argv[i]);
if (stat(currentdir,&dummy) != -1) {
pifd=pipethrough(CPPPATH,currentdir);
readfile(&ohead,&vhead,pifd,&mp);
close(pifd);
printf("done reading %s\n",currentdir);
}
else if (stat(net3ddir,&dummy) != -1) {
pifd=pipethrough(CPPPATH,net3ddir);
readfile(&ohead,&vhead,pifd,&mp);
close(pifd);
printf("done reading %s\n",net3ddir);
}
else {
printf("file %s not found!\n",argv[i]);
exit(0);
}
}
/* check for lack of vehicles */
if (vhead == NULL) {
printf("No vehicles found!\n");
exit(1);
}
/* set up the things usually got from the server */
plcount=1;
pnames[0]="Solo";
makemap(&ohead,&mp);
number=0;
pvehicles[0]=vhead;
/* put the initial game time into the pipe */
sprintf(fakepipe,"%f\n",gametime());
}
else {
char *ver;
/* multi-player mode */
sock=OpenSend(argv[1]);
printf("Connected to server\n");
/* check version */
ver = ngets(sock);
if (strcmp(ver,NET3D_VERSION)) {
nprintf(sock,"%s\n",VERSION_ERROR);
close(sock);
printf("Rejected by server! This client is version %s,"
" but the server is version %s\n",NET3D_VERSION,
ver);
exit(1);
}
if (argc > 2) {
/* if a name is given, use it */
int i;
for(i=2; i<argc; i++) {
strcat(name,argv[i]);
strcat(name," ");
}
}
else {
/* Try to get the user's name from $LOGNAME, $USER or
* cuserid().
*/
char *env_logname, *env_user;
env_logname = getenv("LOGNAME");
env_user = getenv("USER");
if (env_logname)
strcpy(name,env_logname);
else if (env_user)
strcpy(name,env_user);
else
cuserid(name);
}
/* send player's name to the server */
nprintf(sock,"%s\n",name);
/* read the pre-processed vehicle files from the server, for reading
* into the object and vehicle lists.
*/
readfile(&ohead,&vhead,sock,&mp);
printf("done reading vehicles\n");
/* create the map polygons from the map array */
makemap(&ohead,&mp);
/* find player number, and from it the vehicle to drive */
number=atoi(ngets(sock));
if (number==-1) {
printf("no vehicles available :(\n");
shutdown(sock,2);
close(sock);
exit(2);
}
/* read true number of players from server, and from this determine
* which player controls which vehicle
*/
plcount=atoi(ngets(sock));
vpos=vhead;
for(i=0; i<plcount; i++) {
pvehicles[i] = vpos;
vpos->owner = o_network;
vpos->pnum = i;
vpos = vpos->next;
}
/* read names of all players from the server */
for(i=0; i<plcount; i++) {
pnames[i]=strdupe(ngets(sock));
printf("player %d is %s\n",i,pnames[i]);
}
}
/* display some useful info to the player */
worldinfo(vhead,ohead);
printcontrols();
drive=pvehicles[number];
drive->pnum = number;
printf("You are player %d, driving vehicle %s\n",number,drive->code);
/* setup 3-d world */
drive->owner=o_player;
drvid = drive->vid;
alive=true;
initX(&mp, argc, argv);
initmightsaves(ohead);
initmightsaves(eohead);
readicons();
playertype = findbycode(evhead,"player")->type;
/* set up initial viewing parameters */
vw.d=EYE_DISTANCE;
createcamera(drive,&vw,vmode,&mp,vhead);
vw.last.n = vw.last.u = vw.last.v = zpoint;
vw.last.vrp = vw.vrp;
vw.last.vmode = 0;
init3d(&mp,&vw);
ltime=gametime();
calcbboxes(vhead);
/* register functions to be called on break */
if (!singlep) {
signal(SIGINT,termhandler);
signal(SIGTERM,termhandler);
XSetIOErrorHandler(xerrorhandler);
}
/* play the game */
while(1) {
if (alive) {
/* only re-calculate the view if the player still
* lives. once dead, the viewpoint lingers at the
* place of death indefinately :)
*/
createcamera(drive,&vw,vmode,&mp,vhead);
}
/* seed the random number generator with a time from
* the server, to make sure all clients are in sync.
*/
srand(((int)servertime)*1000);
/* draw the 3-d world, and move vehicles in it appropriately,
* but only on the second time around the loop, after a time
* has been read from the server
*/
if (servertime) {
cyclefire(servertime);
worldtoview(&vw,ohead,drive,vmode);
ohead=depthsort(ohead,&vw);
render(&vw,ohead,drive,vmode,&mp);
/* Only draw the radar and info if the player is in the
* cockpit of a vehicle */
if (vmode==4 || vmode==6) {
drawradar(vhead,drive);
drawinfo(drive);
}
if (alive && drive) {
drawvmode(vmode,drive);
drawbuildicons();
}
drawextras(drive,winner);
controlvehicles(&vhead,&ohead);
movevehicles(&vhead,&ohead,&mp,servertime);
growtrees(&vhead,&ohead);
}
if (alive && !drive->alive) {
/* either the player is dead, or they have transfered
* to another vehicle.
*/
if (drive->transfer != -1) {
/* they have transferred */
struct vehicle *v;
/* v = vehicle transferred to */
v = findbyvid(vhead,drive->transfer);
if (!v) {
printf("vid for transfer not found!\n");
exit(20);
}
/* free the old vehicle, and change the drive
* pointer and drvid to indicate that a new vehicle
* is now being driven.
*/
v->owner = drive->owner;
free(drive);
drive = v;
drvid = drive->vid;
}
else {
/* player has just died. Tell the server, and
* clean up their vehicle */
alive=false;
printf("dead\n");
free(drive);
drive=NULL;
if (!singlep) {
/* tell server this client is dead */
nprintf(sock,"d");
}
}
}
#if DISPLAYFPS
/* calculate frames/second */
frm++;
if (frm==100 && servertime) {
double ntime; /* current time */
ntime=servertime;
printf("%lf fps\n",100.0/(ntime-ltime));
ltime=ntime;
frm=0;
}
#endif
#if DISPLAYCACHEINFO
/* display efficiency of map caching */
if (frm == 0) {
double hitpercent;
if (mappointsdone) {
hitpercent = (mapcachehits/(double)mappointsdone) * 100;
printf("map cache %.2lf ",hitpercent);
mapcachehits = mappointsdone = 0.0;
}
if (sincalls) {
hitpercent = (sincachehits / (double)sincalls) * 100;
printf("sin cache %.2lf",hitpercent);
sincachehits = sincalls = 0.0;
}
printf("\n");
}
#endif
/* Read commands and the new game time from the server */
if (singlep)
servertime=readnet(&vhead,&ohead,&winner,&drvid);
else
servertime=readnet(&vhead,&ohead,&winner,&drvid);
/* check for a change in the player's vehicle, after they
* have ejected.
*/
if (drive && drvid != drive->vid) {
/* a new vehicle! search the list for the vehicle
* structure matching the new vid.
*/
drive = findbyvid(vhead,drvid);
if (!drive) {
printf( "The vid for the ejected player doesn't\n"
"match any in the list!!!\n");
exit(20);
}
}
/* If the player is still alive, call readkeys() as normal,
* otherwise pass in a NULL to indicate that the player is
* dead.
*/
if (alive) {
if (singlep)
readkeys(&vmode,drive,vhead,servertime);
else
readkeys(&vmode,drive,vhead,servertime);
}
else {
if (singlep)
readkeys(&vmode,NULL,vhead,servertime);
else
readkeys(&vmode,NULL,vhead,servertime);
}
/* After death, start the final countdown and exit when it REAches 0.
*/
if (!alive && singlep)
if (!(finalcountdown--))
exit(0);
}
/* close connection to the server */
if (!singlep) {
shutdown(sock,2);
close(sock);
}
return(0);
}
static void displayhelp(char *cn)
{
printf(
"net3d client help\n"
"-----------------\n"
"Single player mode : To start net3d in single-player mode, type :\n"
" %s <vehicle file> <vehicle file> ... \n"
" Vehicle files have the extension .v, and at least\n"
" one must be given. If multiple vehicle files are\n"
" listed, then the last vehicle in the last file will\n"
" be the one driven in the game.\n"
"\n"
" For example, if you typed %s map.v tank.v\n"
" then you would be controlling a tank, among scenery\n"
" and other vehicles from map.v\n"
"\n"
"\n"
"Multiplayer mode : To start net3d in multi-player (networked) mode, type :\n"
" %s <server> <name>\n"
" <server> is the machine on which the net3d server is\n"
" running, and <name> is the name identifying you in\n"
" the game. The vehicle you control in the game is\n"
" determined by the server, which assigns a vehicle to\n"
" each player.\n"
,cn,cn,cn);
}